package edu.sjsu.cs.queryopt.dbms.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Scanner;

public class CalCard {
	static Hashtable <Integer, ArrayList<String>> prediTable = new Hashtable <Integer, ArrayList<String>>();
	/**
	 * Plan table 4 Case
	 * CASE: SELECT * from T1
	 * 
	 * */
	static ArrayList<String> fake = new ArrayList<String>();
	static int orandor = 0;
	static String stringOrExtra = "";
	static String textPartForOr = "";
	static WordCapsule  wc = new WordCapsule();
	static SelectHelper sh = new SelectHelper();
	static CreateTable ct = new CreateTable();
	static Helper hp = new Helper();
	 static FilterFactor ff = new FilterFactor();
	 static InList in = new InList();
	 static AccessTypeOne ato = new AccessTypeOne();
	 static CalCard cc = new CalCard();
	 static boolean onlyor = false;
	//PlanTable 1
	
	
	public float calFF(int CardValue){
		float reVal = (float)1/(float)CardValue;
//		System.out.println("FF " + reVal);
		return reVal;
		
	}
	/**
	 * @throws FileNotFoundException 
	 * 
	 * */
	public void CountCalOne(ArrayList<String> output ,
			ArrayList<String> conditionpod ,
			ArrayList<String> frontColpod ,
				ArrayList<String> tablepod ) throws FileNotFoundException
	{
		 Scanner queryFile = null;
//		System.out.println("/----CC1-----/");
//		System.out.println("output " + output);
//		System.out.println("conditionpod " + conditionpod);
//		System.out.println("frontColpod " + frontColpod);
//		System.out.println("tablepod " + tablepod);
		
		if(frontColpod.get(0).trim().equals("*")){
//			System.out.println("CASE : SELECT * FROM SOME CONDIDTION");
			
		}
		else{
			/**
			 * CASE SELECT T1.5 FROM T1 WHERE T1.2 = F AND T1.3 = John
			 * */
			
//			System.out.println("And In listtc " + conditionpod );
			if(conditionpod.contains("AND") || conditionpod.contains("OR") ||  conditionpod.contains("IN")){
				
				
				
				Hashtable<String, ArrayList<String>> listtc = in.getALLPedicate(conditionpod);
				for(int i = 0 ; i < listtc.size() ; i++){
//				System.out.println("listtclisttc " + listtc);
				if(listtc.get("IN").size() > 0){
//					System.out.println("conditionpod " + conditionpod);
//					System.out.println("WE HAVE IN LIST");
					Hashtable <Integer, ArrayList<String>> ht = new Hashtable <Integer, ArrayList<String>>();
					ArrayList<String> pren = new ArrayList<String>();
					for(int index = 0 ; index < conditionpod.size() ; index++){
						
					}
//					dsfsd
				}
				if(listtc.get("OR").size() > 0){
//					System.out.println("WE HAVE IN OR");
					String tbname = "";
					int reme =0;
					int trak = 0;
					ArrayList<String> orChecker = new ArrayList<String>();
					ArrayList<String> number = new ArrayList<String>();
					for(int index = 0 ; index < conditionpod.size() ; index++){
						if(conditionpod.get(index).trim().startsWith("T")){
								trak++;
							if(!orChecker.contains(conditionpod.get(index))){
							orChecker.add(conditionpod.get(index));
							tbname = conditionpod.get(index);
							}
							if(conditionpod.get(index).trim().equals("WHERE")){
								reme = index;
							}
						}
						if(conditionpod.get(index).trim().startsWith("=")){
							number.add(conditionpod.get(index+1));
							
						}
					}
					if(orChecker.size() > 0 && listtc.get("AND").size() == 0 &&listtc.get("IN").size() == 0 ){
							orandor = orChecker.size();
							//onlyor
							if(orandor == 1){
								onlyor = true;
							}
							stringOrExtra += tbname + " ( ";
							for(int o = 0 ;  o < number.size() ;  o ++){
								stringOrExtra += " " + number.get(o)+  ",";
							}
							stringOrExtra += " )";
							
					}
					for(int k = reme ;  k < conditionpod.size() ; k ++){
						textPartForOr +=  conditionpod.get(k)+ " " ;
					}
					String numcol = GetNumOfCalbyreadingline(ato.getTableName(tbname)+".tab");
					
//					 System.out.println("lemma slep " + GetRangeFFIN(Integer.toString(trak),numcol));
//public String GetRangeFFIN(String numofLi , String CardVal)
					fake.add("I");
					fake.add(numcol);// c1
					fake.add(" ");//c2
					fake.add(GetRangeFFIN(Integer.toString(trak),numcol));//ff1
					fake.add(" ");//ff2
					fake.add("1");//seq
					fake.add(textPartForOr);
					fake.add(stringOrExtra);
//					System.out.println("dsafads " + DBMS.PlanTable);
					
					
				}
				if(listtc.get("AND").size() > 0){
//					System.out.println("WE HAVE IN AND " + listtc);
					Hashtable <Integer, ArrayList<String>> ht = new Hashtable <Integer, ArrayList<String>>();
					ArrayList<String> pren = new ArrayList<String>();
					int col1 = 0;
					
							 col1 = 0;
							for(int index = 0 ; index <conditionpod.size() ; index++ ){
								
								if(NotAndOrIn(conditionpod.get(index).trim())){
									
									pren.add(conditionpod.get(index).trim());
								}
								else{
									
									ht.put(col1, pren);
									col1++;
									pren = new ArrayList<String>();
								}
								 
							}
							ht.put(col1, pren); // need to add one more because this program
											  // does't know how to add last one
//							System.out.println("ht currentfgdsg " + ht);
							GetInforForPD(ht);
							ff.FindSeq();
							pren = new ArrayList<String>(); // clear list to re-use
							return;
					
				}
			}
		}
			else{
//				System.out.println("Something CC1 like WHERE T1.5 = T2.4");
				Hashtable <Integer, ArrayList<String>> ht = new Hashtable <Integer, ArrayList<String>>();
				ht.put(0, conditionpod);
				GetInforForPD(ht);
				ff.FindSeq();
						
			}

			
		}

}
							
	
	/**
	 * Get num of literals
	 * WHERE T1.4 IN ( 10 , 20 , 30 ) -> return 3
	 * 
	 * @param  ArrayList<String> condition
	 * @return number literals
	 * */
	public int getNumOfInter(ArrayList<String> al)
	{
		int start =  0;
		int end = 0 ;
		for(int i = 0 ; i < al.size() ; i ++)
		{
			if(al.get(i).trim().equals("(")){
				start = i;
			}
			if(al.get(i).trim().equals(")")){
				end = i;
			}
			
		}
		return (end-1) -start;
	}
	
	/**
	 * GetInforForPD : function to gnerate the pasic infor for Preicate table
	 * @param  Hashtable <Integer, ArrayList<String>> ht : {1=[T1.3, <, 100], 0=[T1.2, >, T1.3]}
	 * @return meaningless...like my life...
	 * */
	public void GetInforForPD(Hashtable <Integer, ArrayList<String>> ht) throws FileNotFoundException{
		ArrayList<String> DupPredi = new ArrayList<String>();
		ArrayList<String> tables = new ArrayList<String>();
		ArrayList<String> cc = new ArrayList<String>();
		ArrayList<String> Result = new ArrayList<String>();
//		System.out.println("In  GetInforForPD " +ht );
		for(int first = 0 ; first < ht.size() ; first++){
			if(CollectType(ht.get(first)).equalsIgnoreCase("E")){
//				System.out.println("Matching PD");
//				System.out.println(" GetInforForPD EQUAL " + ht);
				DupPredi = ht.get(first);
//				System.out.println("DupPredi PD " + DupPredi);
				tables = CollectTableName(DupPredi);
//				System.out.println("tables " + tables);
				cc = GetOneColEqual(tables);
//				System.out.println("GetInforForPD  cc " + tables + "  " + cc);
				Result.add("E"); // Add type first
				/**
				 * Inserting  C1, C2
				 * */
				for(int index = 0 ; index < cc.size() ; index++)
				{
					Result.add(cc.get(index));
					
				}
				for(int second = 0 ; second < cc.size() ; second++)
				{
					if(cc.get(second).equals(" ")){
						Result.add(" ");
					}
					else{
						Result.add(Float.toString(calFF(Integer.parseInt(cc.get(second)))));
					}
				}
//				System.out.println("Result plz  " + Result);
				Result.add(" ");
				Result.add(hp.ListToString(ht.get(first)));
			}			
			else if(CollectType(ht.get(first)).equalsIgnoreCase("R")){
				
//				System.out.println("Range Predicate " + ht);
				Result.add("R");
				/********/
				DupPredi = ht.get(first);
				tables = CollectTableName(DupPredi);
				cc = GetOneColEqual(tables);
//				System.out.println("Result range " + Result);
//				for(int index = 0 ; index < cc.size() ; index++)
//				{
//					Result.add(cc.get(index));
//					
//				}
//				System.out.println("Result 1 "  + Result);
				/*********/
				if(ht.get(first).contains(wc.QWC_GT))
				{//< case
//					System.out.println("GT THAN I THK");
					DupPredi = ht.get(first);		
//					System.out.println("DupPredi PD " + DupPredi);
					tables = CollectTableName(DupPredi);
//					System.out.println("tables " + tables);
					ArrayList<String> Coltype = ct.GetColTypes(sh.getTableName(tables.get(0)).trim()+".tab");
					String colnum = sh.GetColNumber(tables.get(0));
					cc = GetOneColEqual(tables);
//					System.out.println("cc " +cc );
					if(Coltype.get(Integer.parseInt(colnum)-1).charAt(0) == 'C')
					{// THIS IS CHAR TYPE
//						System.out.println("RANGE PRODICATE WITH CHAR " +DupPredi.get(2) );
						String s = Character.toString(DupPredi.get(2).charAt(1)).toLowerCase();
						String f = Character.toString(DupPredi.get(2).charAt(0)).toLowerCase();
//						System.out.println("f " + f);
//						System.out.println("s " + s);
						String HightwoKey = (GetHighTwoKey(tables.get(0)));
						String LowtwoKey = (GetLowTwoKey(tables.get(0)));
						int numberf =  AlpList(f);
						int numbers = AlpList(s);
						int result = (26*numberf)+(1*numbers);
						String ltv = Integer.toString(result);
//						System.out.println("ltvltv " + ltv);
//						System.out.println("HightwoKey " + HightwoKey);
//						System.out.println("LowtwoKey " + LowtwoKey);
						
						String hf =Character.toString(HightwoKey.charAt(0)).toLowerCase();
						String hs =Character.toString(HightwoKey.charAt(1)).toLowerCase();
//						System.out.println("hfhfhf " + hf);
//						System.out.println("hfhfhf " + hs);
						int numberhf =  AlpList(hf);
						int numberhs = AlpList(hs);
//						System.out.println("numberhf " + numberhf);
//						System.out.println("numberhs " + numberhs);
						int resulth = (26*numberhf)+(1*numberhs);
//						System.out.println("resulth " + resulth);
						String lf =Character.toString(LowtwoKey.charAt(0)).toLowerCase();
						String ls =Character.toString(LowtwoKey.charAt(1)).toLowerCase();
						int numberlf =  AlpList(lf);
						int numberls = AlpList(ls);
						int resultl = (26*numberlf)+(1*numberls);
						String htv = Integer.toString(resulth);
						String tvl = Integer.toString(resultl);
						
						//AlpList
//						System.out.println("gt gt + " + htv + " " + tvl + " " + ltv);
//						System.out.println("dsfsdf " + cc);
//						System.out.println("dsfsdfResult 2 " + Result);
						for(int index = 0 ; index < cc.size() ; index++){
							Result.add(cc.get(index));
						}
//						Result.add(" ");
						Result.add(GetRangeFFGT(htv ,tvl,  ltv));
//						System.out.println("dsfsdfResult 3" + Result);
						//Result.add(hp.ListToString(ht.get(first)));
//						System.out.println("dsfsdfResult 4" + Result);
						Result.add(" ");
					}
					else
					{// THIS IS INT
						String HightwoKey = (GetHighTwoKey(tables.get(0)));
						String LowtwoKey = (GetLowTwoKey(tables.get(0)));
						String LiteralVal = (DupPredi.get(DupPredi.size()-1));
//						System.out.println("HightwoKey " + HightwoKey);
//						System.out.println("lowtwoKey " + LowtwoKey);
//						System.out.println("LiteralVal " + LiteralVal);
						for(int index = 0 ; index < cc.size() ; index++){
							Result.add(cc.get(index));
						}
						Result.add(GetRangeFFGT(HightwoKey ,LowtwoKey,  LiteralVal));
						
					
					}
					Result.add(" ");
					Result.add(hp.ListToString(ht.get(first)));
//					System.out.println("last ? " + Result);
					
					
				}
				else if(ht.get(first).contains(wc.QWC_LS))
				{//> case
//					System.out.println("LT THAN I THK");
					DupPredi = ht.get(first);		
//					System.out.println("DupPredi PD " + DupPredi);
					tables = CollectTableName(DupPredi);
//					System.out.println("tables " + tables);
					ArrayList<String> Coltype = ct.GetColTypes(sh.getTableName(tables.get(0)).trim()+".tab");
					String colnum = sh.GetColNumber(tables.get(0));
					cc = GetOneColEqual(tables);
//					System.out.println("cc " +cc );
					if(Coltype.get(Integer.parseInt(colnum)-1).charAt(0) == 'C')
					{// THIS IS CHAR TYPE
//						System.out.println("RANGE PRODICATE WITH CHAR " +DupPredi.get(2) );
						String s = Character.toString(DupPredi.get(2).charAt(1)).toLowerCase();
						String f = Character.toString(DupPredi.get(2).charAt(0)).toLowerCase();
//						System.out.println("f " + f);
//						System.out.println("s " + s);
						String HightwoKey = (GetHighTwoKey(tables.get(0)));
						String LowtwoKey = (GetLowTwoKey(tables.get(0)));
						int numberf =  AlpList(f);
						int numbers = AlpList(s);
						int result = (26*numberf)+(1*numbers);
						String ltv = Integer.toString(result);
//						System.out.println("ltvltv " + ltv);
//						System.out.println("HightwoKey " + HightwoKey);
//						System.out.println("LowtwoKey " + LowtwoKey);
						
						String hf =Character.toString(HightwoKey.charAt(0)).toLowerCase();
						String hs =Character.toString(HightwoKey.charAt(1)).toLowerCase();
//						System.out.println("hfhfhf " + hf);
//						System.out.println("hfhfhf " + hs);
						int numberhf =  AlpList(hf);
						int numberhs = AlpList(hs);
//						System.out.println("numberhf " + numberhf);
//						System.out.println("numberhs " + numberhs);
						int resulth = (26*numberhf)+(1*numberhs);
//						System.out.println("resulth " + resulth);
						String lf =Character.toString(LowtwoKey.charAt(0)).toLowerCase();
						String ls =Character.toString(LowtwoKey.charAt(1)).toLowerCase();
						int numberlf =  AlpList(lf);
						int numberls = AlpList(ls);
						int resultl = (26*numberlf)+(1*numberls);
						String htv = Integer.toString(resulth);
						String tvl = Integer.toString(resultl);
						
						//AlpList
//						System.out.println("gt gt + " + htv + " " + tvl + " " + ltv);
						Result.add(" ");
						Result.add(GetRangeFFLT(htv ,tvl,  ltv));
						
						
					}
					else
					{// THIS IS INT
						String HightwoKey = (GetHighTwoKey(tables.get(0)));
						String LowtwoKey = (GetLowTwoKey(tables.get(0)));
						String LiteralVal = (DupPredi.get(DupPredi.size()-1));
//						System.out.println("HightwoKey " + HightwoKey);
//						System.out.println("lowtwoKey " + LowtwoKey);
//						System.out.println("LiteralVal " + LiteralVal);
//						System.out.println("> result before " + Result);
						for(int index = 0 ; index < cc.size() ; index++){
							Result.add(cc.get(index));
						}
//						System.out.println("> result " + Result);
						Result.add(GetRangeFFLT(HightwoKey ,LowtwoKey,  LiteralVal));
						Result.add(" ");
						
					}
					Result.add(" ");
					Result.add(hp.ListToString(ht.get(first)));


					
				}
				else{
					System.err.println("Might be Range predicate but not for this project");
				}
				
				
				
			}
			else if(CollectType(ht.get(first)).equalsIgnoreCase("IN"))
			{
//				System.out.println("IN LIST CASE" + ht.get(first));
//				System.out.println("sadas " + CalCard.prediTable);
				String lastname = "";
				String name = "";
				Result.add("I");
				int counter = 0;
				for(int index = 0 ; index < ht.get(first).size() ; index++ ){
					lastname += ht.get(first).get(index);
					if(ht.get(first).get(index).trim().startsWith("T")){
						name = ht.get(first).get(index);
					}
					if( !ht.get(first).get(index).equals("(")
							&&!ht.get(first).get(index).equals("(")&&
									!ht.get(first).get(index).equals("IN") && !ht.get(first).get(index).equals(" "))
					{
						if(startWithNum(ht.get(first).get(index))){
							counter++;
						}
						
					}
					
				}
				String textname = "";
				int start = 0 ;
				int end = 0 ;
				for(int index = 0 ; index < ht.get(first).size() ; index++){
					textname+= ht.get(first).get(index)+ " ";
					
				}
				String nameme = "";
				String value = "";
				for(int index = 0 ; index < ht.get(first).size() ; index++){
					if(ht.get(first).get(index).equals("(")){
						start = index;
						value = ht.get(first).get(index+1);
					}
					if(ht.get(first).get(index).equals(")")){
						
							end = index;
						 
					}
					if(ht.get(first).get(index).startsWith("T")){
						nameme = ht.get(first).get(index);
					}
					
				}
				
				//GetNumOfCal  ,  GetRangeFFIN(counter , );
//				System.out.println("counter  counter " + end  + " - " + start);

				String numcol = GetNumOfCalbyreadingline(ato.getTableName(name)+".tab");
//				System.out.println("numcol " + numcol);
				Result.add(numcol);
				Result.add(" ");
				Result.add(GetRangeFFIN( Integer.toString(counter) , numcol));
				Result.add(" ");
				Result.add(" ");
				Result.add(textname); // here
				if((end-start-1) == 1){
					
					Result.add(nameme + " = " + value);
				}
				
//				GetNumOfCal();
			}
			else{
				System.err.println("GetInforForPD: ERROR This is somehting else ");
				
			}
			System.out.println();
			tables = new ArrayList<String>();
//			System.out.println("Result dsfasdsfsd" + Result);
			prediTable.put(first, Result);
			Result = new ArrayList<String>();
		}
//		System.out.println("prediTable CC1 " + prediTable);
		
		
	}
	public boolean startWithNum(String num){
		if((num.startsWith("1") )||(num.startsWith("2")) ||(num.startsWith("3")) ||(num.startsWith("4")) ||
				(num.startsWith("5")) ||
						(num.startsWith("6")) ||
								(num.startsWith("7")) ||
										(num.startsWith("8")) ||
												(num.startsWith("9")) ||
														(num.startsWith("0")))
														{
			return true;
		}
												return false;
	}
	
	/**
	 * CAL FOR FF GT "IN'
	 * Need to use (Literal value - LOW2KEY value) / (Total Entries)
	 * 
	 * @param High2Key
	 * @param Low2key
	 * @param LiteralVal
	 * 
	 * @return FF Valie
	 * 
	 * */
	public String GetRangeFFIN(String numofLi , String CardVal)
	{// <  (Literal value - LOW2KEY value) / (Total Entries)
		double numli = Double.parseDouble(numofLi);
		double card = Double.parseDouble(CardVal);
		
		double result = 0.0;
		
		result =  numli/card;
		
		return Double.toString(result);
	}
	
	/**
	 * CAL FOR FF GT ">'
	 * Need to use (Literal value - LOW2KEY value) / (Total Entries)
	 * 
	 * @param High2Key
	 * @param Low2key
	 * @param LiteralVal
	 * 
	 * @return FF Valie
	 * 
	 * */
	public String GetRangeFFGT(String High2Key , String Low2key , String LiteralVal)
	{// <  (Literal value - LOW2KEY value) / (Total Entries)
//		System.out.println("High2Key " + High2Key);
//		System.out.println("Low2key " + Low2key);
//		System.out.println("LiteralVal " + LiteralVal);
		double hi = Double.parseDouble(High2Key);
		double low = Double.parseDouble(Low2key);
		double li = Double.parseDouble(LiteralVal);
		double result = 0.0;
		
		result =  (li - low) /(hi-low);
		if(result < 0){
			
			result = 0;
		}
		
		return Double.toString(result);
	}
	/**
	 * CAL FOR FF LT "<'
	 * Need to use (Literal value - LOW2KEY value) / (Total Entries)
	 * 
	 * @param High2Key
	 * @param Low2key
	 * @param LiteralVal
	 * 
	 * @return FF Valie
	 * 
	 * */
	
	public String GetRangeFFLT(String High2Key , String Low2key , String LiteralVal)
	{// >  (HIGH2KEY value - Literal value) / (Total Entries)
		double hi = Double.parseDouble(High2Key);
		double low = Double.parseDouble(Low2key);
		double li = Double.parseDouble(LiteralVal);
		double result = 0.0;
		
		result =  (hi - li) /(hi-low);
		if(result < 0){
			
			result = 0;
		}
		
		
		return Double.toString(result);
	}
	
	/**
	 * get High Two Key
	 * @param String: table name and col name .. like T1.1
	 * @param String: converted int value
	 * @throws FileNotFoundException 
	 * */
	public String GetLowTwoKey(String TableAndCol) throws FileNotFoundException
	{
		ArrayList<String> MappedTable = new ArrayList<String>();
		ArrayList<String> OneCol = new ArrayList<String>();
		String tablename = sh.getTableName(TableAndCol);
		String ColNum = sh.GetColNumber(TableAndCol);
		MappedTable = ct.MappingOrignalTable((tablename+wc.tablefiletype).trim());
		int TOTCALnum = GetNumOfCal((tablename+wc.tablefiletype).trim());
		OneCol = ct.GetOneColumn(MappedTable, Integer.parseInt(ColNum) , TOTCALnum );
		Collections.sort(OneCol, String.CASE_INSENSITIVE_ORDER);
		//System.out.println("OneCol high2" + OneCol);
		return OneCol.get(0);
	}
	/**
	 * get Low two Key
	 * @throws FileNotFoundException 
	 * 
	 * */
	public String GetHighTwoKey(String TableAndCol) throws FileNotFoundException
	{
		ArrayList<String> MappedTable = new ArrayList<String>();
		ArrayList<String> OneCol = new ArrayList<String>();
		String tablename = sh.getTableName(TableAndCol);
		String ColNum = sh.GetColNumber(TableAndCol);
		MappedTable = ct.MappingOrignalTable((tablename+wc.tablefiletype).trim());
		int TOTCALnum = GetNumOfCal((tablename+wc.tablefiletype).trim());
		OneCol = ct.GetOneColumn(MappedTable, Integer.parseInt(ColNum) , TOTCALnum );
		Collections.sort(OneCol, String.CASE_INSENSITIVE_ORDER);
		//System.out.println("OneCol low2 " + OneCol);
		return OneCol.get(OneCol.size()-1);
	}

	
	/**
	 * Get one col from the mapped table
	 * 
	 * @param String : Table name with Col -> 
	 * 
	 * */
	
	public ArrayList<String> GetOneColEqual(ArrayList<String> TableAndColNum) throws FileNotFoundException{
		
		ArrayList<String> MappedTable = new ArrayList<String>();
		ArrayList<String> OneCol = new ArrayList<String>();
		ArrayList<String> reAl = new ArrayList<String>();
		int cardinality = 0;
		/**
		 *1. Call Mapping function to get whole table form file
		 *2. Call GetNumOfCal to get size of col in one row
		 *3. Call the GetOneColumn function to get One col
		 * */
		for(int index = 0; index < TableAndColNum.size() ; index++){
			String tablename = sh.getTableName(TableAndColNum.get(index));
			String ColNum = sh.GetColNumber(TableAndColNum.get(index));
			MappedTable = ct.MappingOrignalTable((tablename+wc.tablefiletype).trim());
			int TOTCALnum = GetNumOfCal((tablename+wc.tablefiletype).trim());
			OneCol = ct.GetOneColumn(MappedTable, Integer.parseInt(ColNum) , TOTCALnum );
//			System.out.println("TOTCALnum  " + TOTCALnum );
			reAl.add(Integer.toString(DistinctNumer(OneCol)));
			
			
		}
		/**
		 * We need to add  C1 , C2  same time. If predicate is local then we need to insert
		 * empty space for C2 part.
		 * */
		if(reAl.size() < 2){
			reAl.add(" ");
			
		}
//		
//		System.out.println("reAl " + reAl);
		return reAl;

	}
	
	public int DistinctNumer(ArrayList<String> oneCol ){
		
		ArrayList<String> al = new ArrayList<String>();
		
		for(int index = 0 ; index < oneCol.size(); index++){
			if(!al.contains(oneCol.get(index))){
				al.add(oneCol.get(index));
				
			}
		}
		return al.size();
		
	}
	
	/**
	 * get size of col of getting col
	 * @param String : table name
	 * 
	 * @return sizd of col in table
	 * 
	 * */
	public int GetNumOfCal(String tbname) throws FileNotFoundException
	{
		//int reVal = 0;
		int index = 0;
		String EachLineInTable = "";
		Scanner queryFile = null;
		ArrayList<String> list = new ArrayList<String>();
		 File file =  new File(tbname);
		queryFile = new Scanner(file);
//		System.out.println("sadfasd " + tbname);
		
		while (queryFile.hasNextLine()) {
			
			if(index == 2){
				EachLineInTable = queryFile.nextLine();
				break;
				
			}
			
			index++;
		}
		list = hp.StringToArrayList(EachLineInTable);
		
//		System.out.println(" GetNumOfCal  " + list);
		return list.size();
		
	}
	
	public String GetNumOfCalbyreadingline(String tbname) throws FileNotFoundException
	{
		//int reVal = 0;
		int index = 0;
		String EachLineInTable = "";
		Scanner queryFile = null;
		ArrayList<String> list = new ArrayList<String>();
		queryFile = new Scanner(new File(tbname));
		
		while (queryFile.hasNextLine()) {
			EachLineInTable = queryFile.nextLine();
			if(index == 1){
				
				break;
				
			}
			index++;
			
		}
		
		
		
		return EachLineInTable;
		
	}
	
	
	/**
	 * Checking Type
	 * */
	public String CollectType(ArrayList<String> conditionpod)
	{
		//ArrayList<String> ReTypes = new ArrayList<String>();
//		System.out.println("conditionpod dsf " + conditionpod);
		for(int index = 0 ; index < conditionpod.size(); index++){
			if(conditionpod.get(index).trim().equals(wc.QWC_EQUAL)){
				return "E";
			}
			else if(conditionpod.get(index).trim().equals(wc.QWC_GT)
					|| conditionpod.get(index).trim().equals(wc.QWC_LS))
			{
				return "R";
			}
			else if(conditionpod.get(index).trim().equals("IN")){
				return "IN";
			}
		}
		
		return "SOME THING ELSE";
	}

	/**
	 * Get the Table and col name from the each Predicate
	 * 
	 * How ? TABLE form in condition is something like " T1.1"
	 * Detecting "." to find table and col
	 * 
	 * @param ArrayList<String> : like [WHERE, T1.2, =, M]
	 * 
	 * @return T1.2
	 * 
	 * */
	public ArrayList<String> CollectTableName(ArrayList<String> conditionpod)
	{
		ArrayList<String> tables = new ArrayList<String>();
		
		for(int index = 0 ; index < conditionpod.size() ; index++){
			
			if(conditionpod.get(index).contains(".")){
				tables.add(conditionpod.get(index));
			}
			
		}
		//System.out.println("CollectTableName: tables " + tables);
		return tables;
	}

	
	
	/**
	 * Calculate the Card Value and FF for case 4
	 * 
	 * It is handling 1: SELECT * FROM TABLE
	 * OR
	 * 2: SELECT COLS FROM TABLE
	 * 
	 * @param ArrayList<String>: index list
	 * @param ArrayList<String> : Condition
	 *  @param ArrayList<String> : frontColpod: after select
	 *   @param ArrayList<String> : tablepod: After F	From
	 * */
	public void CountCalFour(ArrayList<String> output ,
				ArrayList<String> conditionpod ,
					ArrayList<String> frontColpod ,
						ArrayList<String> tablepod ) throws FileNotFoundException
	{
		 Scanner queryFile = null;
//		System.out.println("/----CC4-----/");
//		System.out.println("output " + output);
//		System.out.println("conditionpod " + conditionpod);
//		System.out.println("frontColpod " + frontColpod);
//		System.out.println("tablepod " + tablepod);
		/**
		 * error checking 
		 * */
		if(!sh.IsSelectColCorrent(tablepod, frontColpod))
		{
			System.err.println("ERROR : UN-MATCH TABLE NAME IN CASE 4");
		}
		
		int index = 0;
		int Number = 0;
		if(frontColpod.get(0).trim().equals(wc.QWC_Star))
		{
			 queryFile = new Scanner(new File(tablepod.get(0)+wc.tablefiletype));
			 while (queryFile.hasNextLine()) {
				 
				 String fileLine = queryFile.nextLine();
				 if(index == 1){
//					 System.out.println("Card Number for case 4 - 1 : " + fileLine);
					 Number =  Integer.parseInt(fileLine.trim());
				 }
				 index++;
			 }
		}
		else{
//			System.out.println("SELECT COL_NAME FROM TABLE_NAME ");
			
			 queryFile = new Scanner(new File(tablepod.get(0)+wc.tablefiletype));
			 while (queryFile.hasNextLine()) {
				 
				 String fileLine = queryFile.nextLine();
				 if(index == 1){
//					 System.out.println("Card Number for case 4 - 2 : " + fileLine);
					 Number =  Integer.parseInt(fileLine.trim());
				 }
				 index++;
			 }
		}
		// if there is predicate
		if(conditionpod.size() > 1){
		calFF(Number);
		}
		
	}
	public boolean NotAndOrIn(String op){
		if(!op.equalsIgnoreCase("AND")&&
				!op.equalsIgnoreCase("OR")){
				return true;
			
		}
		return false;
	}
	public static String getHighKeyForIndex(String tablename)  throws IOException{
		BufferedReader br = new BufferedReader(new FileReader(tablename+".tab"));
  		String line = "";
  		int trakcer = 0;
  		String re = "";
  		while((line = br.readLine()) != null ){
  			
  			if(trakcer == 2){
  				
  				re = line;
  			}
  			
  			trakcer++;
  		}
		return re;
		
	}
	public static String getLowKeyForIndex(String tablename)  throws IOException{
		BufferedReader br = new BufferedReader(new FileReader(tablename+".tab"));
  		String line = "";
  		int trakcer = 0;
  		String re = "";
  		while((line = br.readLine()) != null ){
  			re = line;
  		
  		}
  		
  		return re;
		
	}
	/**
	 * GETTING SIZE OF TABLE FOR PLAIN TABLE TABLE CARD PARD
	 * IF WE HAVE ONLY ONE TABLE THEN ADD EMPTY SPACE AT THE LAST OF FUNCTION
	 * 
	 * @param ArrayList<String> tablename
	 * @return non  adding card table part in this function 
	 * */
  public void getTableCards(ArrayList<String> tables) throws IOException{
	  	ArrayList<String> AllTableContainer = new ArrayList<String>();
	  	int tracker = 0;
//	  	System.out.println("tables tables " + tables);
	  	for(int index = 0 ; index < tables.size() ; index++)
	  	{
	  		BufferedReader br = new BufferedReader(new FileReader(tables.get(index).trim()+".tab"));
	  		String line = "";
	  		while((line = br.readLine()) != null && tracker <1){
	  			tracker++;
	  		}
//	  		System.out.println("line  " + line);
	  		AllTableContainer.add(String.valueOf(line));
	  		br.close();
	  		tracker = 0;

	  	}
		tracker = 0;
	  	if(AllTableContainer.size() == 0){
	  		AllTableContainer.add(" ");
	  	}
	  	for(int i = 0 ; i <  AllTableContainer.size() ; i++){
	  		DBMS.PlanTable.add(AllTableContainer.get(i));
	  	}
	  	
	  
	
	
}
  public int AlpList(String a){
	  ArrayList<String> al= new ArrayList<String>();
	  al.add("a");
	  al.add("b");
	  al.add("c");
	  al.add("d");
	  al.add("e");
	  al.add("f");
	  al.add("g");
	  al.add("h");
	  al.add("i");
	  al.add("j");
	  al.add("k");
	  al.add("l");
	  al.add("m");
	  al.add("n");
	  al.add("o");
	  al.add("p");
	  al.add("q");
	  al.add("r");
	  al.add("s");
	  al.add("t");
	  al.add("u");
	  al.add("v");
	  al.add("w");
	  al.add("x");
	  al.add("y");
	  al.add("z");
	 
	  for(int index = 0 ; index < al.size() ; index++){
		  if(al.get(index).equals(a.trim())){
//			  System.out.println("AlpList " + (index+1));
			  return (index+1);
		  }
	  }
	return 0;
   }

	
}
